Skip to content

Conversation

@cbegeman
Copy link
Collaborator

@cbegeman cbegeman commented Oct 27, 2025

This PR adds a customizable visualization task for data on MPAS meshes. It has two steps, viz_horiz_field and viz_transect. viz_transect is not run by default but technically either steps is optional. This task does not have a climatology function and thus doesn't produce analogous plots to MPAS-Analysis. It makes use of plot_global_mpas_field (which in turn uses mosaic) and plot_transect from mpas_tools.ocean.viz.transect.

Checklist

  • User's Guide has been updated
  • Developer's Guide has been updated
  • API documentation in the Developer's Guide (api.md) has any new or modified class, method and/or functions listed
  • Documentation has been built locally and changes look as expected
  • Testing comment in the PR documents testing used to verify the changes
  • New tests have been added to a test suite

@cbegeman
Copy link
Collaborator Author

Example images produced by this PR:
image

image

@cbegeman
Copy link
Collaborator Author

@andrewdnolan and @xylar let me know what you think of a task like this one. I know there's a lot more that could be done to generalize this so I see this PR more as a first step that we could build on.

@xylar
Copy link
Collaborator

xylar commented Oct 29, 2025

@cbegeman, sorry for the delay on this. I'll take a look tomorrow but at a glance it looks really exciting!

Copy link
Collaborator

@xylar xylar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really handy! A few small comments for now.

def determine_time_variable(ds):
prefix = ''
time_variable = None
if 'timeSeriesStatsMonthly' in ds.keys():
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think timeSeriesStatsMonthly will be a data variable. Should this be xtime_startMonthly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea.

Comment on lines +45 to +51
cell_indices = np.where(
(ds_mesh.maxLevelCell > 0)
& (lat_cell >= min_latitude)
& (lat_cell <= max_latitude)
& (lon_cell >= min_longitude)
& (lon_cell <= max_longitude)
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This culling process is a little bit risky because cells with centers outside the range may nevertheless have vertices in the range and the boundary may look ragged with this approach.

Also, many projections don't have straight edges in latitude/longitude space so this may drop cells that should appear within the project bounds. Might it be better to have mosaic try to do this kind of optimization and not try to handle it on the Polaris side?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrewdnolan, do you have thoughts on this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or I could just check lonVertex/latVertex instead of cell centers?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is okay for cell-centered fields, though I might need to give it a bit more thought.

What we definitely need to do is iterate over the list of variables and make sure they are cell fields. (Only if this culling does subset the mesh, otherwise no restriction on them having to be cell-fields).

@xylar and I have talked about adding a more complete regional masking functionality (which would replicate the culler), which accepts a cell mask but would allow plotting cell, edge, or vertex fields. That's definitely something I can put at the top of the mosiac development priorities.

Copy link
Collaborator

@andrewdnolan andrewdnolan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Thanks for putting it together @cbegeman.

Most of my comments mainly have to do with mosaic limitations. Hopefully I can start tackling some of these limitations soon!

Comment on lines +45 to +51
cell_indices = np.where(
(ds_mesh.maxLevelCell > 0)
& (lat_cell >= min_latitude)
& (lat_cell <= max_latitude)
& (lon_cell >= min_longitude)
& (lon_cell <= max_longitude)
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is okay for cell-centered fields, though I might need to give it a bit more thought.

What we definitely need to do is iterate over the list of variables and make sure they are cell fields. (Only if this culling does subset the mesh, otherwise no restriction on them having to be cell-fields).

@xylar and I have talked about adding a more complete regional masking functionality (which would replicate the culler), which accepts a cell mask but would allow plotting cell, edge, or vertex fields. That's definitely something I can put at the top of the mosiac development priorities.

if z_index != 0:
filename_suffix = f'_z{z_index}'

if self.config.has_option(section_name, 'colormap_name'):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since colormap only accepts a string, all variables requested will be plotted with the same colormap (if the colormap is specified). Same goes for vmin / vmax.

I think this is fine for now, especially given the viz_dict you've defined. Might be something to tackle later, cause it could cause some unexpected behavior.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I wasn't really sure how much to build out the customization options here. I feel like commented lists aren't great because the user will eventually lose track of the correspondence between variable and options. I also wasn't sure how much we wanted this task to be a stepping stone to MPAS-A. Probably easier to have a conversation some time about philosophically where to go with this.

Copy link
Collaborator

@xylar xylar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cbegeman, this looks good to me. It will be an excellent starting point for porting MPAS-Analysis capabilities to Polaris in the near future.

@cbegeman
Copy link
Collaborator Author

@xylar Thank you! I'll merge after adding some docs.

@cbegeman cbegeman marked this pull request as ready for review November 10, 2025 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants